package org.karelun.rabbit.rcp.editpart;

import java.util.List;

import org.eclipse.draw2d.ChopboxAnchor;
import org.eclipse.draw2d.ConnectionAnchor;
import org.eclipse.draw2d.Figure;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.swt.widgets.Display;
import org.karelun.ideaboard.gef.ConnectionEditPart;
import org.karelun.ideaboard.gef.EditPolicy;
import org.karelun.ideaboard.gef.NodeEditPart;
import org.karelun.ideaboard.gef.Request;
import org.karelun.ideaboard.gef.editparts.AbstractGraphicalEditPart;
import org.karelun.rabbit.graph.Connection;
import org.karelun.rabbit.graph.GraphPackage;
import org.karelun.rabbit.graph.Shape;
import org.karelun.rabbit.rcp.policy.DeleteShapeEditPolicy;
import org.karelun.rabbit.rcp.policy.ShapeConnectionEditPolicy;

public class ShapeEditPart extends AbstractGraphicalEditPart implements NodeEditPart, Adapter{
	
	private Notifier target;
	
	private EditingDomain editingDomain;
	
	public ShapeEditPart(EditingDomain editingDomain){
		this.editingDomain=editingDomain;
	}
	
	@Override
	protected IFigure createFigure() {
		return new Figure(){
			@Override
			protected void paintFigure(Graphics graphics) {
				super.paintFigure(graphics);
				Rectangle r = getBounds();
				Rectangle rect=new Rectangle(r.x,r.y,r.width-1,r.height-1);
				graphics.drawRectangle(rect);
			}
		};
	}

	@Override
	protected void createEditPolicies() {
		installEditPolicy(EditPolicy.COMPONENT_ROLE, new DeleteShapeEditPolicy());
		installEditPolicy(EditPolicy.GRAPHICAL_NODE_ROLE, new ShapeConnectionEditPolicy());
	}
	
	@Override
	public void activate() {
		super.activate();
		((Shape)getModel()).eAdapters().add(this);
	}
	
	@Override
	public void deactivate() {
		((Shape)getModel()).eAdapters().remove(this);
		super.deactivate();
	}
	
	@Override
	public void notifyChanged(Notification notification) {
		int featureID = notification.getFeatureID(GraphPackage.class);
		switch (featureID) {
		case GraphPackage.SHAPE__X:
		case GraphPackage.SHAPE__Y:
		case GraphPackage.SHAPE__HEIGHT:
		case GraphPackage.SHAPE__WIDTH:
		{
			Runnable runnable = new Runnable(){
				public void run() {
					refreshVisuals();
				}
			};
			Display.getDefault().asyncExec(runnable);
			break;
		}
		case GraphPackage.SHAPE__SOURCE_CONNECTIONS:
		{
			Runnable runnable=new Runnable(){
				public void run() {
					refreshSourceConnections();
				}
			};
			Display.getDefault().asyncExec(runnable);
			break;
		}
		case GraphPackage.SHAPE__TARGET_CONNECTIONS:
		{
			Runnable runnable=new Runnable(){
				public void run() {
					refreshTargetConnections();
				}
			};
			Display.getDefault().asyncExec(runnable);
			break;
		}
		}
	}
	
	@Override
	protected void refreshVisuals() {
		Shape shape=(Shape)getModel();
		Dimension size = new Dimension(shape.getWidth(), shape.getHeight());
		Point point = new Point(shape.getX(),shape.getY());
		Rectangle rectangle = new Rectangle(point, size);
		((DiagramEditPart)getParent()).setLayoutConstraint(this, getFigure(), rectangle);
	}

	@Override
	public Notifier getTarget() {
		return target;
	}

	@Override
	public void setTarget(Notifier newTarget) {
		this.target=newTarget;
	}

	@Override
	public boolean isAdapterForType(Object type) {
		return type.equals(getModel().getClass());
	}
	
	@Override
	protected List<Connection> getModelSourceConnections() {
		Shape shape=(Shape)getModel();
		return shape.getSourceConnections();
	}
	
	@Override
	protected List<Connection> getModelTargetConnections() {
		Shape shape=(Shape)getModel();
		return shape.getTargetConnections();
	}

	@Override
	public ConnectionAnchor getSourceConnectionAnchor(ConnectionEditPart connection) {
		return new ChopboxAnchor(getFigure());
	}

	@Override
	public ConnectionAnchor getTargetConnectionAnchor(ConnectionEditPart connection) {
		return new ChopboxAnchor(getFigure());
	}

	@Override
	public ConnectionAnchor getSourceConnectionAnchor(Request request) {
		return new ChopboxAnchor(getFigure());
	}

	@Override
	public ConnectionAnchor getTargetConnectionAnchor(Request request) {
		return new ChopboxAnchor(getFigure());
	}
	@Override
	public Object getAdapter(Class key) {
		if(key==EditingDomain.class){
			return editingDomain;
		}
		return super.getAdapter(key);
	}
}
